/**
* It works on Air runtime environment. 
*/
package net.sangpil.applications.viewer
{
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	import flash.net.FileFilter;
	
	import net.sangpil.applications.viewer.event.SkinVideoEvent;
	import net.sangpil.classes.events.VideoWithUrlEvent;
	import net.sangpil.classes.media.video.VideoWithUrl;
	import net.sangpil.classes.utils.bitmap.GetBitmap;

	[Event(name = "video_loaded", type = "net.sangpil.applications.viewer.event.SkinVideoEvent")]
	[Event(name = "video_replay", type = "net.sangpil.applications.viewer.event.SkinVideoEvent")]
	public class SkinVideo extends Sprite
	{
		public var vid:VideoWithUrl;
		private var skin:Navi_VideoPlayerClip;
		private var file:File;
		private var fileFilter:FileFilter;
		
		private var skin_width:Number;
		private var skin_height:Number;
		
		private var loopTf:Boolean;
		private var realtimeBar:Boolean;
		
		private var spr:Sprite;
		
		/**
		 * expected this video size
		 * @param width 
		 * @param height  
		 * 
		 */		
		public function SkinVideo(width:Number, height:Number = 28.75, loop:Boolean = true, realtimeBar:Boolean = true)
		{
			super();
			this.skin_width = width;
			this.skin_height = height;			
			this.loopTf = loop;
			this.realtimeBar = realtimeBar;
			
			this.addEventListener(Event.ADDED_TO_STAGE, onStage);	
		}
		
		/* public function */
		/**
		 * when change flv url. 
		 * @param url
		 * 
		 */		
		public function movieLoad(url:String):void
		{
			this.vid.movieLoad(url);
		}
		
		/**
		 * read only. 
		 * @return bitmapData from video.
		 * 
		 */		
		public function get bitmapData():BitmapData
		{
			var bmd:BitmapData = GetBitmap.getBitmap(this.spr, this.vid.width, this.vid.height);
			//trace(bmd.width, bmd.height);
			return bmd;
		} 
		
		/* private function */
		
		/**
		 * make video(vid), file, fileFilter, skin instances 
		 * and make controller as default size
		 */		
		private function init():void
		{
			this.vid = new VideoWithUrl(320, 240, this.loopTf);
			this.vid.addEventListener(VideoWithUrlEvent.VIDEO_LOADED, setLayout);
			this.vid.addEventListener(VideoWithUrlEvent.VIDEO_REPLAY, setLayout);
			this.spr = new Sprite();
			this.addChild(spr);
			
			this.fileFilter = new FileFilter("Movie File", "*.flv");
			this.file = new File();
			file.addEventListener(Event.SELECT, onSelected);
			
			this.skin = new Navi_VideoPlayerClip();
			this.addChild(this.skin);
			
			this.skin.btn_play.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			this.skin.btn_pause.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			this.skin.bar_progress.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			this.skin.btn_browse.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			
			this.skin.btn_browse.buttonMode = true;
			
			this.setControlPosition(this.skin_width, 1);
		}
		
		/**
		 * set controller bar size depand on video size.  
		 * @param w
		 * @param h
		 * @param selectedStr url text param
		 * 
		 */		
		private function setControlPosition(w:Number, h:Number, selectedStr:String = "Video : Open Browser"):void
		{
			this.skin.y = h;
			this.skin.bg_second.width = w;
			this.skin.btn_browse.width = w;
			this.skin.bar_progress.width = w - this.skin.bar_progress.x;
			this.skin.txt_url.width = w-10; 
			this.skin.txt_url.text = selectedStr;
			//this.skin.txt_url.autoSize = TextAlign.LEFT;
		}
		
		/**
		 * when file selected. 
		 * @param e
		 * 
		 */		
		private function onSelected(e:Event):void
		{
			var temp:File = e.target as File;
			trace(temp.url);
			
			this.vid.movieLoad(temp.url);
		}
		
		/* event handler */		
		
		private function onStage(e:Event):void
		{
			this.init();
		}
		
		/**
		 * video controller navigation eventhandler 
		 * @param e
		 * 
		 */		
		private function onDown(e:MouseEvent):void
		{
			switch(e.currentTarget.name)
			{
				case "btn_play": 
					this.vid.resume();
				break;
				case "btn_pause":
					this.vid.pause(); 
				break;
				case "bar_progress": 
					//trace(this.vid.currentFrame);
					if(this.realtimeBar)
					{
						this.removeEventListener(Event.ENTER_FRAME, onEnter);
					}
					e.currentTarget.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
					e.currentTarget.addEventListener(MouseEvent.MOUSE_UP, onUp);
					e.currentTarget.addEventListener(MouseEvent.MOUSE_OUT, onOut);
					this.skin.bar_progress.progressBar.width = e.currentTarget.mouseX;
					var n:Number = Math.round(this.vid.duration*e.currentTarget.mouseX*10)/1000;
					this.vid.seek(n);
					this.vid.pause();
				break;
				case "btn_browse": 
					file.browse([this.fileFilter]);	
				break;
			}
		}
		
		/**
		 * when video loaded. rescale video(vid) with ratio
		 * @param e
		 * 
		 */		
		private function setLayout(e:VideoWithUrlEvent):void
		{
			//trace(e.info.duration, e.info.width, e.info.height);
			this.spr.addChild(this.vid);
			var ratio:Number =  this.skin_width / this.vid.width;
			
			this.vid.width = this.skin_width;
			this.vid.height *= ratio;
			
			trace("movie rescale");
			this.setControlPosition(this.vid.width, this.vid.height, e.info.url);
			if(this.realtimeBar)
			{
				this.addEventListener(Event.ENTER_FRAME, onEnter);
			}
			if(e.type == VideoWithUrlEvent.VIDEO_LOADED)
			{
				this.dispatchEvent(new SkinVideoEvent(SkinVideoEvent.VIDEO_LOADED));
			}else{
				this.dispatchEvent(new SkinVideoEvent(SkinVideoEvent.VIDEO_REPLAY));
			}
		}
		
		private function onEnter(e:Event):void
		{
			this.skin.bar_progress.progressBar.width =  Math.round(this.vid.currentFrame/this.vid.duration*1000)/10; 
		}
		
		private function onUp(e:MouseEvent):void
		{
			if(this.realtimeBar)
			{
				this.addEventListener(Event.ENTER_FRAME, onEnter);
			}
			e.currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
			e.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, onUp);
			e.currentTarget.removeEventListener(MouseEvent.MOUSE_OUT, onOut);
			var n:Number = Math.round(this.vid.duration*e.currentTarget.mouseX*10)/1000;
			this.vid.seek(n);
			this.vid.resume();
		}
		
		private function onOut(e:MouseEvent):void
		{
			if(this.realtimeBar)
			{
				this.addEventListener(Event.ENTER_FRAME, onEnter);
			}
			e.currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
			e.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, onUp);
			e.currentTarget.removeEventListener(MouseEvent.MOUSE_OUT, onOut);
			var n:Number = Math.round(this.vid.duration*e.currentTarget.mouseX*10)/1000;
			this.vid.seek(n);
			this.vid.resume();
		}
		
		private function onMove(e:MouseEvent):void
		{
			this.skin.bar_progress.progressBar.width = e.target.mouseX;
			var n:Number = Math.round(this.vid.duration*e.currentTarget.mouseX*10)/1000;
			this.vid.seek(n);
			this.vid.pause();
		}
		
	}
}